package main

import (
	"context"
	"fmt"
	"go.etcd.io/etcd/client/v3"
	"time"
)

func main() {
	var (
		config         clientv3.Config
		client         *clientv3.Client
		err            error
		lease          clientv3.Lease
		leaseGrantResp *clientv3.LeaseGrantResponse
		leaseId        clientv3.LeaseID
		getResp        *clientv3.GetResponse
		putResp        *clientv3.PutResponse
		kv             clientv3.KV
		keepResp       *clientv3.LeaseKeepAliveResponse
		keepRespChan   <-chan *clientv3.LeaseKeepAliveResponse
	)
	config = clientv3.Config{
		Endpoints:   []string{"47.106.109.134:2379"},
		DialTimeout: 5 * time.Second,
	}
	if client, err = clientv3.New(config); err != nil {
		fmt.Println(err)
		return
	}

	// 申请租约
	lease = clientv3.NewLease(client)

	// 申请10秒租约
	if leaseGrantResp, err = lease.Grant(context.TODO(), 10); err != nil {
		fmt.Println(err)
		return
	}

	// lease ID
	leaseId = leaseGrantResp.ID

	// kv
	kv = clientv3.NewKV(client)

	// put kv 与租约关联
	if putResp, err = kv.Put(context.TODO(), "cron/jobs/job1", "", clientv3.WithLease(leaseId)); err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println("wrote suc: ", putResp.Header.Revision)

	go func() {
		// 自动续租
		ctx, _ := context.WithTimeout(context.TODO(), 5*time.Second)

		// 自动续租5秒
		if keepRespChan, err = lease.KeepAlive(ctx, leaseId); err != nil {
			fmt.Println(err)
			return
		}
		for {
			select {
			case keepResp = <-keepRespChan:
				if keepResp == nil {
					fmt.Println("auto lease cancel")
					goto END
				} else {
					fmt.Println("auto lease suc: ", keepResp.TTL)
				}
			}
		}
	END:
	}()

	// 查看key是否过期
	for {
		fmt.Println(time.Now())
		if getResp, err = kv.Get(context.TODO(), "cron/jobs/job1"); err != nil {
			fmt.Println(err)
			return
		}
		if getResp.Count == 0 {
			fmt.Println("kv expired")
			break
		}
		fmt.Println("kv: ", getResp.Kvs)
	}
}
